function extractNumber(element, attributeSelector) {
  return parseFloat(extractTitle(element, attributeSelector));
}

function extractTitle(element, attributeSelector) {
  return $(element).find(attributeSelector).first().attr("title");
}

var map;

function plotMarkers(markers) {
  map.objects.clear();

  $.each(markers, function(index, marker) {
    map.objects.add(marker);
  });
}

function getMarkersFromElement(element) {
  var markers = [];

  $(element).find('.marker').each(function(index, markerElement) {
    var link = $(markerElement).find('a').first();
    var icon = link.find('img').first();
    var marker = new nokia.maps.map.Marker(
      new nokia.maps.geo.Coordinate(extractNumber(markerElement, '.latitude'), extractNumber(markerElement, '.longitude')),{
        title: icon.attr('alt'),
        visibility: true,
        icon: icon.attr('src'),
        // Offset the top left icon corner so that it's centered above the coordinate
        anchor: new nokia.maps.util.Point(32, 32)
      }
    );
    marker.addListener("click", function (evt) {
      window.open (link.attr('href'),'_self',false)
    });
    markers.push(marker)
  });

  return markers;
}

function getBoundaryBoxCoveringAllMarkers(markers) {
  return nokia.maps.geo.BoundingBox.coverAll( getCoordsFromMarkers(markers));
}

function initializeMap() {
  $('#map').each(function(index, element) {
    var markers = getMarkersFromElement(element);
    var boundingBoxCoveringAllMarkers = getBoundaryBoxCoveringAllMarkers(markers);

    map = new nokia.maps.map.Display(element, {
      components: [new nokia.maps.map.component.Behavior(),
                   new nokia.maps.map.component.ZoomBar(),
                   new nokia.maps.map.component.Overview(),
                   new nokia.maps.map.component.ScaleBar()],
      zoomLevel: 13,
      center: boundingBoxCoveringAllMarkers.getCenter()
    });

    var explore = function(){
        var url = "/vegetarian/data?" + jQuery.param({viewport: getBoundaryBoxAsString()});

        $.get(url, function( data ) {
           $('.data').replaceWith(data);
           var mapElement = $('#map');
           var markers = getMarkersFromElement(mapElement);
           plotMarkers(markers);
           mapElement.find('.data').hide();
       });
    }

    map.addListener("mapviewchangeend", explore);

    map.zoomTo(boundingBoxCoveringAllMarkers, false, "none");

    plotMarkers( markers);
    $(element).find('.data').hide();
    listenForEnterKey();
  });
}

function getCoordsFromMarkers(markers) {
  return $.map(markers, function(marker) {
    return marker.coordinate;
  });
}

function listenForEnterKey() {
  var suggestBox = $("#suggestbox")
  suggestBox.keypress(function(event) {
    if (event.keyCode==13) {
      suggestBox.autocomplete('close');
      runNewSearch(suggestBox.attr('value'));
    }
  });
}

function getBoundaryBoxAsString() {
  //         bot      left      top        right
  //         long /\  lat >     long /\    lat >
  // berlin: 13.08835 ,52.33812,13.76134,52.6755
  var bounds = map.getViewBounds();
  var bottomRight = bounds.bottomRight;
  var topLeft = bounds.topLeft;
  return [topLeft.longitude,bottomRight.latitude,bottomRight.longitude,topLeft.latitude].join(",");
}

function getMapCentre() {
  var centreCoordinate = map.getViewBounds().getCenter();
  return [centreCoordinate.latitude, centreCoordinate.longitude];
}

$(function() {
  $( "#suggestbox" ).autocomplete({
    source: function( request, response ) {
      var base_url = $("#pbapi-base-url").attr("value");
      var credentials = $("#pbapi-credentials").attr("value");
      $.ajax({
        url: base_url+"/suggest?"+credentials+"&at="+getMapCentre().join(","),
        dataType: "jsonp",
        data: {q: request.term},
        headers: {'Accept-Encoding': 'gzip', 'Accept': 'application/json'},
        success: function( data ) { response(data.suggestions); }
      });
    },
    minLength: 2,
    select: function( event, ui ) {
      $('#map').text = ui.item;
      runNewSearch( ui.item.label);
    }
  });
});

function runNewSearch( searchTerm) {
  var url = "/search?" + jQuery.param({q: searchTerm, viewport: getBoundaryBoxAsString()});

  $.get(url, function( data ) {
    $('.data').replaceWith(data);
    var mapElement = $('#map');
    var markers = getMarkersFromElement(mapElement);
    plotMarkers(markers);
    map.zoomTo(getBoundaryBoxCoveringAllMarkers(markers));
    mapElement.find('.data').hide();
  });
}
